package de.baumann.browser.utils.update

import android.app.Activity
import android.app.DownloadManager
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.provider.Settings
import android.support.v4.content.FileProvider
import de.baumann.browser.R
import java.io.File
import java.lang.ref.WeakReference

class AppDownloadManager(activity: Activity) : DownloadReceiver.DownloadCompleteListener {

    private val tag = "AppDownloadManager"
    private var weakReference: WeakReference<Activity>? = null
    private var mDownloadManager: DownloadManager? = null
    private var mDownloadReceiver: DownloadReceiver? = null
    private var mReqId: Long = 0
    private var apkName:String


    init {
        weakReference = WeakReference(activity)
        mDownloadManager = weakReference?.get()?.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
        mDownloadReceiver = DownloadReceiver()
        mDownloadReceiver!!.downloadCompleteListener = this
        apkName = weakReference?.get()?.getString(R.string.app_name)+".apk"
    }

    fun downloadApk(apkUrl: String, title: String, desc: String) {

        val file = File(weakReference!!.get()!!.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), apkName)
        if (file.exists()) {
            file.delete()
        }

        val request = DownloadManager.Request(Uri.parse(apkUrl))
        request.setTitle(title)
        request.setDescription(desc)
        request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
        request.setDestinationInExternalFilesDir(
            weakReference!!.get(),
            Environment.DIRECTORY_DOWNLOADS,apkName
        )
        request.setMimeType("application/vnd.android.package-archive")
        mReqId = mDownloadManager!!.enqueue(request)
    }

    fun cancel() {
        mDownloadManager!!.remove(mReqId)
    }

    /**
     * [Activity.onResume]
     */
    fun onResume() {
        weakReference!!.get()!!.registerReceiver(
            mDownloadReceiver,
            IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)
        )
    }

    /**
     * [Activity.onPause]
     */
    fun onPause() {
        weakReference!!.get()!!.unregisterReceiver(mDownloadReceiver)
    }

    override fun downloadComplele(context: Context, intent: Intent) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
            installApk(context, intent)
        } else {
            val canRequest = weakReference!!.get()!!.packageManager.canRequestPackageInstalls()
            if (canRequest) {
                installApk(context, intent)
            } else {
                val packageURI = Uri.parse("package:" + weakReference!!.get()!!.packageName)
                val packageIntent = Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, packageURI)
                weakReference!!.get()!!.startActivityForResult(packageIntent, 1000)
            }
        }
    }


    private fun installApk(context: Context, intent: Intent) {
        val completeDownLoadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1)
        if (completeDownLoadId != mReqId) {
            return
        }

        val installIntent = Intent()
        installIntent.action = Intent.ACTION_VIEW
        installIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
        installIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
        installIntent.setDataAndType(getUri(context), "application/vnd.android.package-archive")
        context.startActivity(installIntent)
    }

    private fun getUri(context: Context): Uri? {
        val file = File(weakReference!!.get()!!.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), apkName)
        return if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
            Uri.fromFile(file)
        } else {
            FileProvider.getUriForFile(context, "de.baumann.browser.fileprovider", file)
        }
    }
}